#include "Buffer.h"
#include <iostream>
#include <fcntl.h>

#ifdef _MSC_VER
	#include <io.h>
#endif

#define BUFFER_SIZE 2

Buffer::Buffer(const char* filepath){
        this->mMemory1 = new char[BUFFER_SIZE+1];
        this->mMemory2 = new char[BUFFER_SIZE+1];
        this->mCurrentBuffer = this->mMemory1;
        this->mCurrentPosition = 0;
        this->mLoadNewBuffer = true;
        this->mCanGoBack = false;
        this->mFile = open(filepath, O_RDONLY);
        this->loadBuffer(this->mMemory1);
}

Buffer::~Buffer(){
	delete[] this->mMemory1;
	delete[] this->mMemory2;
}

void Buffer::loadBuffer(char* currentBuffer) {
        int i = read(this->mFile, currentBuffer, BUFFER_SIZE);
        currentBuffer[i] = '\0';
}

void Buffer::switchBuffer() {
        if (this->mMemory1 == this->mCurrentBuffer) {
                this->mCurrentBuffer = this->mMemory2;
        } else {
                this->mCurrentBuffer = this->mMemory1;
        }
}

char Buffer::getChar(){
	std::cout <<  "new" << std::endl;

	// Unter windows funktionierts nicht wegen CR
	if(this->mCurrentBuffer[this->mCurrentPosition] != '\0'){
			// Aktueller Char vom Buffer lesen
			char currentChar = this->mCurrentBuffer[this->mCurrentPosition];
			std::cout << "aktuelles Zeichen: " << currentChar << " (" << (int)currentChar << ")" << std::endl;

			// Position erh�hen
			this->mCurrentPosition++;

			// Pr�fen ob Buffersize beim n�chsten lesen �berschritten ist
			if (this->mCurrentPosition == BUFFER_SIZE) {
					std::cout << "Ende erreicht -> Switch Buffer (n�chste Position > " << BUFFER_SIZE << ")" << std::endl;
					this->mCanGoBack = true;
					this->switchBuffer();
					this->mCurrentPosition = 0;
					std::cout << "n�chste Position auf 0 zur�ckgesetzt" << std::endl;
					if (this->mLoadNewBuffer) {
							this->loadBuffer(this->mCurrentBuffer);
					}
					else {
						this->mLoadNewBuffer = true;
					}
			}
			return currentChar;
	}
	else{
		std::cout << "shit" << std::endl;
			return '\0';
	}
}

void Buffer::ungetChar(int i){
        if (i <= this->mCurrentPosition) {
                this->mCurrentPosition -= i;
        }
        else {
                if ((this->mCanGoBack == true) && (i <= this->mCurrentPosition+BUFFER_SIZE)) {
                        this->switchBuffer();
                        this->mLoadNewBuffer = false;
                        this->mCanGoBack = false;
                        this->mCurrentPosition = BUFFER_SIZE-(i-this->mCurrentPosition);
                }
                else {
                       throw "Error: Maximale gr��e f�r ungetChar(i) wurde �berschritten!";
                }
        }
}
